using System;
using Synapse.Framework.Notifier;
using Synapse.Framework.Pipe.BusinessObjects;
using Synapse.Framework.Pipe.Filters;
using Synapse.Framework.Pipe.Operations;

namespace Synapse.Framework.Pipe.PipeLines
{
    internal class OperationContainer<TFilter, TInput, TPump> : IOperation<TFilter, TInput, TPump> 
    {
        private readonly IResolver resolver;
        private readonly PipeLine pipeLine;
        private readonly INotifier notifier;

        public OperationContainer(IResolver resolver, PipeLine pipeLine, INotifier notifier)
        {
            this.resolver = resolver;
            this.pipeLine = pipeLine;
            this.notifier = notifier;
        }

        public IFilter<TOutput, TPump> Out<TOutput>(Func<TFilter, Func<TInput, TOutput>> func)
        {
            pipeLine.Add(new FilterAOP<TInput, TOutput>(new OperationFuncAdapter<TInput, TOutput>(func((TFilter) resolver.Resolve(typeof (TFilter)))),notifier));
            return new Filter<TOutput, TPump>(resolver, pipeLine,notifier);
        }

        public IFilter<TOutput, TPump> OutObject<TOutput>(Func<TFilter, Func<TInput, _<TOutput>>> func)
        {
            pipeLine.Add(new FilterAOP<TInput, TOutput>(new Operations.OperationFunc<TInput, TOutput>(func((TFilter)resolver.Resolve(typeof(TFilter)))), notifier));
            return new Filter<TOutput, TPump>(resolver, pipeLine, notifier);
        }
    }
}